/*
 * Copyright 2003,2004 The Apache Software Foundation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package eu.jakubiak.jpa.translator.discriminator;

import eu.jakubiak.utils.javabean.BeanProperty;
import eu.jakubiak.utils.javabean.BeanReflector;
import java.lang.reflect.InvocationTargetException;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;

/**
 *
 * @author Antek
 */
public class JpaDiscriminator implements Discriminator {

    public Long discriminate(Object object) {
        // if its not JPA entity then we use simple hash code 
        if (!object.getClass().isAnnotationPresent(Entity.class)) {
            return new HashCodeDiscriminator().discriminate(object);
        }
        // if we have complex primary key then we use simply hash code
        // it's complicated to implement
        if (object.getClass().isAnnotationPresent(IdClass.class)) {
            return new HashCodeDiscriminator().discriminate(object);
        }

        BeanReflector reflector = new BeanReflector(object);
        for (BeanProperty property : reflector.getProperties()) {
            if (property.isAnnotationPresent(Id.class)) {
                return get(property, object);
            }
        }
        return new HashCodeDiscriminator().discriminate(object);
    }

    private Long get(BeanProperty property, Object object) {
        Object id;
        try {
            id = property.get(object);
        } catch (IllegalAccessException ex) {
            return new HashCodeDiscriminator().discriminate(object);
        } catch (IllegalArgumentException ex) {
            return new HashCodeDiscriminator().discriminate(object);
        } catch (InvocationTargetException ex) {
            return new HashCodeDiscriminator().discriminate(object);
        }
        if(Number.class.isInstance(id)) {
            return ((Number)id).longValue();
        }
        return new HashCodeDiscriminator().discriminate(object);
    }
}
